package com.fingard.dsp.bank.directbank.abc02;

import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IForeignCurrency;
import com.fingard.dsp.bank.reqrespobj.foreigncurrsingle.ReqForeignCurrSingle;
import com.fingard.dsp.bank.reqrespobj.foreigncurrsingle.ReqQryForeignCurrSingle;
import com.fingard.dsp.bank.reqrespobj.foreigncurrsingle.RetAtsForeignCurrSingle;
import com.fingard.dsp.bank.reqrespobj.foreigncurrsingle.detail.RetAtsForeignCurrPayDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2017/10/31.
 */
public class ABC02ForeignCurrSinglePay extends ABC02Base implements IForeignCurrency {
    @Override
    public RetAtsForeignCurrSingle foreignCurrPay(ReqForeignCurrSingle reqForeignCurrSingle) throws Exception {
        //返回ATS的对象
        RetAtsForeignCurrSingle retAts = new RetAtsForeignCurrSingle(reqForeignCurrSingle.reqHeader);
        RetAtsForeignCurrPayDetail tmpRetDetail = null;
        if("CrossborderFCP".equals(reqForeignCurrSingle.reqHeader.commandCode)){//跨境外币
            tmpRetDetail = d_gfrb10(reqForeignCurrSingle);
        }else if("DomesticFCP".equals(reqForeignCurrSingle.reqHeader.commandCode)){//境内外币
            tmpRetDetail = d_ds01(reqForeignCurrSingle);
        }else if("OutsideFCP".equals(reqForeignCurrSingle.reqHeader.commandCode)){//全球汇款
            tmpRetDetail = d_os01(reqForeignCurrSingle);
        }else {
            tmpRetDetail = new RetAtsForeignCurrPayDetail();
            tmpRetDetail.respCode = "0";
            tmpRetDetail.respInfo = "无效的指令代码";
            tmpRetDetail.transState = PaymentState.FAIL_Payment;
            tmpRetDetail.payInfoCode = "E1301";
        }
        if(tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)){
            tmpRetDetail.reqSeqID = reqForeignCurrSingle.singleDetail.askNumber;
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    //跨境外币（未测）
    public RetAtsForeignCurrPayDetail d_gfrb10(ReqForeignCurrSingle reqForeignCurrSingle){
        RetAtsForeignCurrPayDetail retDetail = new RetAtsForeignCurrPayDetail();

        try {
            //赋值通用参数
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "GFRB10";
            bankHeader.ReqSeqNo = reqForeignCurrSingle.singleDetail.askNumber;
            bankHeader.ReqDateTime = reqForeignCurrSingle.singleDetail.getPayDateTime();
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入通用的头部节点
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeElementString("Amt", reqForeignCurrSingle.singleDetail.payAmount);
            xmlWriter.writeElementString("ccy", getBankConfig().getMapValueByKey("currencyMapping1",reqForeignCurrSingle.singleDetail.payCur));
            xmlWriter.writeStartElement("Cmp");
            xmlWriter.writeElementString("DbProv", reqForeignCurrSingle.singleDetail.payAreaCode);
            xmlWriter.writeElementString("DbAccNo", getAbcAccNo(reqForeignCurrSingle.singleDetail.payAct));//跨境账号
            xmlWriter.writeElementString("DbCur", convertCurToBank(reqForeignCurrSingle.singleDetail.payCur));
            xmlWriter.writeElementString("CrAccNo", getAbcAccNo(reqForeignCurrSingle.singleDetail.recAct));
            xmlWriter.writeEndElement();
            //需要进行对账码拼接以及节点解析，采用XElement进行处理
            XElement tmpXElement = new XElement("Corp","");
            tmpXElement.addChild(new XElement("OthBankFlag","0"));//0-境内农行1-他行

            /*tmpXElement.addChild(new XElement("DbAccName",reqForeignCurrSingle.singleDetail.payName));
            tmpXElement.addChild(new XElement("DbBankNo",reqForeignCurrSingle.singleDetail.paySWIFTCODE));//收报行BICCODE
            tmpXElement.addChild(new XElement("CrBankNo",reqForeignCurrSingle.singleDetail.recCNAPSCode));//收款行的银行代码
            tmpXElement.addChild(new XElement("CrBankName",reqForeignCurrSingle.singleDetail.recCNAPSName));//收款行的名称地址
            tmpXElement.addChild(new XElement("CrAccName",reqForeignCurrSingle.singleDetail.recName));//收款人的名称地址
            tmpXElement.addChild(new XElement("Postscript",reqForeignCurrSingle.singleDetail.abstractATS));//收款人的名称地址
            nodeAnalysis(reqForeignCurrSingle.singleDetail.srcXElement, tmpXElement, getCharset());*/
            xmlWriter.writeXElement(tmpXElement);

            xmlWriter.writeStartElement("biz");
            //01 结售汇户D0 现汇户D1 待核查户D2 资本户D3 外债户D4 外债户1D5 外债户2D6 外债户3D7 保证金户D8 贷款专户G5 其他账户
            xmlWriter.writeElementString("ac_type", "G5");
            //1 境外-电汇(swift方式)2 港澳台-电汇(swift方式)3 境内-系统内同城4 境内-系统外同城5 境内-系统内异地6 境内-系统外异地
            if("CrossborderFCP".equals(reqHeader.commandCode)) {
                xmlWriter.writeElementString("rem_way", "1");//跨境默认为1

            }
            String costMode = reqForeignCurrSingle.singleDetail.costMode;
            costMode = "SHA".equals(costMode)?"S":"BEN ".equals(costMode)?"B":"OUR ".equals(costMode)?"O":"";
            xmlWriter.writeElementString("charges_details", costMode);//费用负担
            xmlWriter.writeElementString("beneficiary", reqForeignCurrSingle.singleDetail.recName);//收款人
            xmlWriter.writeElementString("bene_addr1", reqForeignCurrSingle.singleDetail.recAddr);//收款人地址1（街道门牌号）
            xmlWriter.writeElementString("bene_addr2", reqForeignCurrSingle.singleDetail.recAddr);//收款人地址2（城市）
            xmlWriter.writeElementString("ac_bank_fld", "A");//账户行ABD A-swift D-行名和地址 默认为A

            xmlWriter.writeElementString("ac_bank_name", reqForeignCurrSingle.singleDetail.recSWIFTCODE);//收款人账户行
            xmlWriter.writeElementString("int_bank_fld", "");//中间行ABD
            xmlWriter.writeElementString("int_bank_name", "");//中间行
            xmlWriter.writeElementString("bene_type", "1".equals(reqForeignCurrSingle.singleDetail.isPrivate)?"1":"0");//收款人类型0 对公1 对私
            xmlWriter.writeElementString("pay_details", reqForeignCurrSingle.singleDetail.purpose);//付款详情
            xmlWriter.writeElementString("postscript", reqForeignCurrSingle.singleDetail.purpose);//附言 todo
            //汇款用途 0 国外贸易支出1 国外非贸易支出2 境外投资3 偿还外债4 国内贸易支出5 国内非贸易支出6 其它7 其它资本支出
            xmlWriter.writeElementString("usage", "6");//默认其他
            xmlWriter.writeElementString("country", reqForeignCurrSingle.singleDetail.recCountryCode);//收款人国家代码
            xmlWriter.writeElementString("pay_type", reqForeignCurrSingle.singleDetail.payMethod);//付款类型
            xmlWriter.writeElementString("pay_attr", reqForeignCurrSingle.singleDetail.payProperty);//付款性质
            xmlWriter.writeElementString("tx_code1", reqForeignCurrSingle.singleDetail.transCode1);//交易编码1
            xmlWriter.writeElementString("tc_amt1", reqForeignCurrSingle.singleDetail.amout1);//相应金额1
            xmlWriter.writeElementString("tx_rem1", reqForeignCurrSingle.singleDetail.postScript1);//交易附言1
            xmlWriter.writeElementString("tx_code2", reqForeignCurrSingle.singleDetail.transCode2);//交易编码2
            xmlWriter.writeElementString("tc_amt2", reqForeignCurrSingle.singleDetail.amout2);//相应金额2
            xmlWriter.writeElementString("tx_rem2", reqForeignCurrSingle.singleDetail.postScript2);//交易附言2
            xmlWriter.writeElementString("is_ref", "1".equals(reqForeignCurrSingle.singleDetail.isBondedGood)?"Y":"N");//是否保税货物项下付款
            xmlWriter.writeElementString("crt_user", reqForeignCurrSingle.singleDetail.contactPerson);//申请人姓名
            xmlWriter.writeElementString("inp_telc", reqForeignCurrSingle.singleDetail.contactNum);//申请人电话
            xmlWriter.writeElementString("contr_no", reqForeignCurrSingle.singleDetail.contractNo);//合同号
            xmlWriter.writeElementString("invoi_no", reqForeignCurrSingle.singleDetail.invoiceNo);//发票号
            xmlWriter.writeElementString("reg_no", reqForeignCurrSingle.singleDetail.businessNum);//外汇局批件/备案表号


            /*String custRefFlag = getBankConfig().getValueAsString("custRefFlag");
            if("".equals(custRefFlag)||custRefFlag==null) {
                xmlWriter.writeElementString("CustRefFlag", "0");//是否使用客户内部编码 0不使用1使用 为1时CustRef必填
            }else {
                xmlWriter.writeElementString("CustRefFlag", "1");
            }
            xmlWriter.writeElementString("CustRef", custRefFlag);//客户内部编码
            String payDate = reqForeignCurrSingle.singleDetail.payDate;
            payDate = payDate.substring(0,4)+payDate.substring(5,7)+payDate.substring(8);
            xmlWriter.writeElementString("ReqExecDate", payDate);//要求支付款项的日期
            String payCur = !StringHelper.isNullOrEmpty(reqForeignCurrSingle.singleDetail.payCashAct)?getBankConfig().getMapValueByKey("currencyMapping1",reqForeignCurrSingle.singleDetail.payCur):"CNY";
            String fxDealRefFlg = !StringHelper.isNullOrEmpty(reqForeignCurrSingle.singleDetail.transCode1)?"1":"0";
            xmlWriter.writeElementString("ActualCcy", payCur);//实际支付币种
            xmlWriter.writeElementString("ActualAmt", payCur+reqForeignCurrSingle.singleDetail.payAmount.replace(".",","));//实际支付金额 小数点替换为逗号（奇怪的需求）
            xmlWriter.writeElementString("ExRateFlag", "0");//是否使用协定汇率 0不使用 1使用
            xmlWriter.writeElementString("ExRate", "0");//协定汇率
            xmlWriter.writeElementString("FXDealRefFlg", fxDealRefFlg);//是否使用外汇买卖交易编号 0不使用 1使用
            xmlWriter.writeElementString("FXDealRef", reqForeignCurrSingle.singleDetail.transCode1);//外汇买卖交易编号
            xmlWriter.writeElementString("UseParentAccFlag","0");//是否使用母公司账户统一对外支付 0不使用 1使用
            xmlWriter.writeElementString("SubCompName","0");//子公司名称
            xmlWriter.writeElementString("ChargeDtl",reqForeignCurrSingle.singleDetail.costMode);//汇款国内外费用承担
            xmlWriter.writeElementString("FeeAccFlag",reqForeignCurrSingle.singleDetail.payAct.equals(reqForeignCurrSingle.singleDetail.feeAct)?"1":"0");//收费账户是否与跨境汇出账户一致
            xmlWriter.writeElementString("FeeAccNo",reqForeignCurrSingle.singleDetail.feeAct);//收费账号
            xmlWriter.writeElementString("CodeType","");//todo need收款行代码类别,清算中心报文不需要*/
            xmlWriter.writeEndDocument();//写入报文完成
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());//发送银行
            if(tmpStrRet[0].length() == 0){
                StringBuilder tmpSbMsg = new StringBuilder();
                //解析银行返回
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if(tmpBkReader != null){
                    String tmpRespCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    String tmpRespSource = tmpBkReader.getFirstText("/ap/RespSource");

                    retDetail.respCode = "0";
                    retDetail.reqSeqID = reqForeignCurrSingle.singleDetail.askNumber;
                    retDetail.transState = tmpRespSource + "+" + tmpRespCode;
                    retDetail.payInfoCode = tmpRespCode;
                    retDetail.respInfo = StringHelper.joinNotEmpty("+", tmpRetInfo,tmpRetRxtInfo);
                }
                else{
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            }
            else if(tmpStrRet[0].equals(ConnState.FAIL)){
                retDetail.respCode = "0";
                retDetail.respInfo = tmpStrRet[1];
                retDetail.reqSeqID = reqForeignCurrSingle.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = tmpStrRet[0];
            }
            else{
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            retDetail.respCode = "-1";
            retDetail.respInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        return retDetail;
    }
    public RetAtsForeignCurrPayDetail d_ds01(ReqForeignCurrSingle reqForeignCurrSingle){
        RetAtsForeignCurrPayDetail tmpRetDetail = new RetAtsForeignCurrPayDetail();
        tmpRetDetail.respCode = "-1";
        tmpRetDetail.respInfo = "暂不支持境内外币付款接口";
        return tmpRetDetail;
    }
    public RetAtsForeignCurrPayDetail d_os01(ReqForeignCurrSingle reqForeignCurrSingle){
        RetAtsForeignCurrPayDetail tmpRetDetail = new RetAtsForeignCurrPayDetail();
        tmpRetDetail.respCode = "-1";
        tmpRetDetail.respInfo = "暂不支持全球汇款接口";
        return tmpRetDetail;
    }
    @Override
    //GQLT16
    public RetAtsForeignCurrSingle qryForeignCurrPay(ReqQryForeignCurrSingle reqQryForeignCurrSingle) throws Exception {
        //返回ATS的对象
        RetAtsForeignCurrSingle retAts = new RetAtsForeignCurrSingle(reqQryForeignCurrSingle.reqHeader);

        RetAtsForeignCurrPayDetail tmpRetAtsDetail = new RetAtsForeignCurrPayDetail();
        tmpRetAtsDetail.respCode = "";
        if(tmpRetAtsDetail.respCode.length() == 0){
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "GQLT16";
            bankHeader.ReqSeqNo = reqQryForeignCurrSingle.reqHeader.transSeqID;
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, bankHeader);//写入通用的头部节点
            xmlWriter.writeStartElement("Cme");
            xmlWriter.writeElementString("SerialNo",reqQryForeignCurrSingle.askNumber);
            xmlWriter.writeEndDocument();
            try{
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
                if(tmpStrRet[0].length() == 0){
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if(tmpBkReader != null){
                        String tmpRespCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        //String tmpRespSource = tmpBkReader.getFirstText("/ap/RespSource");
                        if (tmpRespCode.equals("0000")){
                            tmpRetAtsDetail.respCode = "0";
                            tmpRetAtsDetail.reqSeqID = reqQryForeignCurrSingle.askNumber;
                            //1|待复核|2|未复核完成|3|正在发送|4|已处理|5|交易失败|6|落地待处理|7|预约受理|
                            //8|交易取消|9|交易状态未知|A|柜台已出单|B|拒绝复核|C|正在复核|D|批量交易尚未处理|H|交易发送至账户行|J|账户行拒绝|S|支付申请未打印|U|修改作废|
                            String status = tmpBkReader.getFirstText("/ap/Cmp/TransSta");
                            tmpRetAtsDetail.transState = tmpRespCode+"+"+status;//todo 未在数据库维护并且未找到已支付标志
                            tmpRetAtsDetail.respInfo =  tmpRetInfo;
                            tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
                        }
                        else{
                            tmpRetAtsDetail.respCode = "-1";
                            if(!StringHelper.isNullOrEmpty(tmpRetRxtInfo)){
                                tmpRetAtsDetail.respInfo = tmpRetRxtInfo;
                            }
                            else{
                                tmpRetAtsDetail.respInfo = tmpRetInfo;
                            }
                        }
                    }
                    else{
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                    }
                }
                else{
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpStrRet[1];
                }
            }
            catch (Exception e) {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = e.getMessage();
                e.printStackTrace();
            }
        }
        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }
}
